﻿using System;
using System.Net;
using System.Net.Sockets;
using Lite.Common;

namespace Lite.Net
{
    internal sealed class SocketListenerMonitor
        : SocketMonitorBase
    {
        private Socket _listener;

        public SocketListenerMonitor(IPAddress address, int port)
        {
            _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _listener.Bind(new IPEndPoint(address, port));
        }

        public override void Start()
        {
            _listener.Listen(50);
            base.Start();
        }

        public override void Halt()
        {
            base.Halt();
            _listener.Listen(0);
        }

        protected override bool BeginAsyncOperation(SocketAsyncEventArgs eventArgs)
        {
            eventArgs.AcceptSocket = null;
            eventArgs.UserToken = this;
            return _listener.AcceptAsync(eventArgs);
        }

        protected override bool CompleteAsyncOperation(SocketAsyncEventArgs eventArgs)
        {
            Socket newSocket = eventArgs.AcceptSocket;

            OnSocketAccepted(newSocket);

            return true;
        }

        private void OnSocketAccepted(Socket socket)
        {
            EventHandler<EventArgs<Socket>> socketAccepted = SocketAccepted;

            if (socketAccepted != null)
            {
                socketAccepted(this, new EventArgs<Socket>(socket));
            }
        }
        
        public event EventHandler<EventArgs<Socket>> SocketAccepted;
    }
}
